/*
 * shared_buffer_mgr.hpp
 *
 *  Created on: 2018年3月21日
 *      Author: Dylan.Gao
 */

#ifndef _DM_OS_SHARED_BUFFER_MGR_HPP_
#define _DM_OS_SHARED_BUFFER_MGR_HPP_

#include <dm/os/types.hpp>
#include <dm/magic.hpp>
#include <typeinfo>
#include <cstdio>
#include <vector>

namespace dm{
namespace os{

/**
 * 共享缓冲区管理器类
 * 实现了基于共享内存的动态数组的管理
 * @tparam TRecord 记录类型
 * @tparam NameOfBuffer 共享内存名字
 * @tparam SizeOfBuffer 单个缓冲区大小
 */
template<typename TRecord,int SizeOfBuffer=64,typename TSize=dm::uint32,typename TIndex=dm::int32>
class TCSharedBufferMgr{
public:
	// 魔数类型
	typedef dm::CMagic::magic_t magic_t;

	/**
	 * 缓冲区信息类型
	 * 记录了缓冲区的全局信息
	 */
	struct SBufferInfo{
		upgradable_mutex_t mutex;	//!< 全局锁。对缓冲区的访问必须加锁。修改时，必须升级锁
		magic_t magic;	//!< 全局魔数。代表了缓冲区发生了变化
		TSize bufCount;	//!< 缓冲区个数
	};


private:
    TCSharedBufferMgr();
    ~TCSharedBufferMgr();
public:
    /**
     * 单例模式获取对象
     * @return
     */
    static TCSharedBufferMgr& ins();

protected:
    /**
     * 获取缓冲区信息名
     * @return
     */
    inline const char* nameOfInfo()const{
    	return typeid(*this).name();
    }

    /**
     * 获取缓冲区名
     * @param name
     * @param index
     */
    inline void nameOfBuffer(char* name,int index)const{
    	std::sprintf(name,"%s-%d",nameOfInfo(),index);
    }

private:
    volatile SBufferInfo* m_info;	//!< 全局信息指针
    magic_t m_magic;	//!< 全局魔数
};

/**
 * 构造函数
 * 创建信息区
 * @tparam TRecord
 * @tparam SizeOfBuffer
 * @tparam size_t
 */
template<typename TRecord,int SizeOfBuffer,typename TSize,typename TIndex>
TCSharedBufferMgr<TRecord,SizeOfBuffer,TSize,TIndex>::TCSharedBufferMgr(){
	const char* name = nameOfInfo();
}

template<typename TRecord,int SizeOfBuffer,typename TSize,typename TIndex>
TCSharedBufferMgr<TRecord,SizeOfBuffer,TSize,TIndex>::~TCSharedBufferMgr(){

}

template<typename TRecord,int SizeOfBuffer,typename TSize,typename TIndex>
TCSharedBufferMgr<TRecord,SizeOfBuffer,TSize,TIndex>& TCSharedBufferMgr<TRecord,SizeOfBuffer,TSize,TIndex>::ins(){
	static TCSharedBufferMgr<TRecord,SizeOfBuffer,TSize,TIndex> ins;
	return ins;
}

}
}
#endif
